package game.screens;

import java.util.Iterator;
import java.util.List;

import game.Game;
import game.Main;
import game.util.ChatModule;
import game.util.MovementModule;
import game.util.TileGraphics;

import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.gui.TextField;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

import shared.Tiles;
import shared.io.game.Player;
import shared.io.game.Room;

/**
 * Main game screen. This is where the game happends.
 */
public class GameScreen extends BasicGameState {
   /**
    * Screen's ID
    */
   public static final int ID = 2;
   private Game game;
   /**
    * Keyboard input
    */
   private Input input;
   /**
    * Textfield for chatting.
    */
   private TextField textField;
   /**
    * On screen chatting.
    */
   private ChatModule chatModule;
   /**
    * Player movement
    */
   private MovementModule movement;
   
   public GameScreen(Game game) {
      this.game = game;
   }
   
   /**
    * Starts up the screen
    */
   @Override
   public void init(GameContainer container, StateBasedGame arg1)
         throws SlickException {
      input = container.getInput();
      textField = new TextField(container, container.getDefaultFont(), 0, Main.HEIGHT - 20, Main.WIDTH, 20);
      chatModule = new ChatModule(game);
      movement = new MovementModule(game);
   }

   /**
    * Rendering. Called based on framerate.
    * Adds all the players, rooms, chat, etc to the screen.
    */
   @Override
   public void render(GameContainer container, StateBasedGame arg1, Graphics g)
         throws SlickException {
      synchronized (game.getRooms()) {
         List<Room> rooms2 = game.getRooms();
         Iterator<Room> it = rooms2.iterator();
         while (it.hasNext()) {
            Room room = it.next();
            synchronized (room) { 
               Image tile;
               if (room.getTile() == Tiles.WALL) {
                  tile = TileGraphics.gfx().getWall();
               } else if (room.getTile() == Tiles.EXIT) {
                  tile = TileGraphics.gfx().getExit();
               } else {
                  tile = TileGraphics.gfx().getFloor();
               }
               tile.setAlpha(room.getLight());
               tile.draw(room.getX() * tile.getWidth(), room.getY() * tile.getHeight());
            }
         }
      }
      for (Player player : game.getPlayers()) {
         Image playerTile = TileGraphics.gfx().getCharSprites()[player.getPlayerColor()];
         playerTile.setFilter(Image.FILTER_NEAREST);
         playerTile.draw(player.getX() * playerTile.getWidth(), player.getY() * playerTile.getHeight(), new Color(0xFFFFFF));
      }
      chatModule.render(container, g, 5, 35);
      textField.render(container, g);
   }

   /**
    * Update (is called much rare than render)
    */
   @Override
   public void update(GameContainer arg0, StateBasedGame arg1, int arg2)
         throws SlickException {
      if (input.isKeyPressed(Input.KEY_ENTER)) {
         if (textField.getText().length() > 0) {
            game.getSession().writeObject(textField.getText());
            textField.setText("");
         } else {
            textField.setFocus(!textField.hasFocus());
         }
      }
      movement.update(input);
      input.clearControlPressedRecord();
      chatModule.update();
   }

   @Override
   public int getID() {
      return ID;
   }

}
